/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package menadzery;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import okna.WidokNowaGra;
import okna.WidokStol;

/**
 *
 * @author sufka
 */
public class Klient {

    private Socket socket;
    private int servPort;
    private String server;
    private static final int BUFSIZE = 64;
    private BufferedReader in;
    private PrintWriter out;
    private Gracz gracz;
    private Integer aktualnaMaxStawka;
    private WidokNowaGra widokNowaGra;
    private WidokStol widokStol;
    private boolean jeszczeNieZmieniajWidoku;
    private Rozgrywka rozgrywka;
    private boolean wymieniane;

    public Klient(WidokNowaGra widokNowaGra) throws IOException {
        this.server = /*"192.168.0.174";*/"localhost";
        this.servPort = 1928;
        this.socket = new Socket(this.server, this.servPort);
        this.aktualnaMaxStawka = 0;
        this.gracz = new Gracz();
        this.in = new BufferedReader(
                new InputStreamReader(
                this.socket.getInputStream()));
        this.out = new PrintWriter(
                this.socket.getOutputStream(), true);
        this.widokNowaGra = widokNowaGra;
        this.widokNowaGra.setKlient(this);
        jeszczeNieZmieniajWidoku = true;
    }

    public Integer getAktualnaMaxStawka() {
        return aktualnaMaxStawka;
    }

    public void setAktualnaMaxStawka(Integer aktualnaMaxStawka) {
        this.aktualnaMaxStawka = aktualnaMaxStawka;
    }

    public boolean isWymieniane() {
        return wymieniane;
    }

    public void setWymieniane(boolean wymieniane) {
        this.wymieniane = wymieniane;
    }

    public Gracz getGracz() {
        return gracz;
    }

    public WidokStol getWidokStol() {
        return widokStol;
    }

    public void setWidokStol(WidokStol widokStol) {
        this.widokStol = widokStol;
    }

    public void setRozgrywka(Rozgrywka rozgrywka) {
        this.rozgrywka = rozgrywka;
    }

    public Rozgrywka getRozgrywka() {
        return rozgrywka;
    }

    public BufferedReader getIn() {
        return in;
    }

    public PrintWriter getOut() {
        return out;
    }

    public void dzialaj() throws IOException {
        this.komunikuj();
        this.in.close();
        this.out.close();
        this.socket.close();
    }

    public String odbierzDane() throws IOException {
        String dane;
        dane = in.readLine();
        return dane;
    }

    public void wyslijDane(String dane) throws IOException {
        this.out.println(dane);
        this.out.flush();
    }

    public void odkodujStaty(String stat) {
        Integer c = new Integer(stat.charAt(0) - 48);
        switch (c) {
            case 0:
                rozgrywka.setLiczbaGraczy(new Integer(stat.charAt(1) - 48));
                //     System.out.println(stat.charAt(1)+" rozmiar "+rozgrywka.getLiczbaGraczy());
                break;
            case 1:
                // if( this.getGracz() == null ) System.out.println("brak gracza");
                //    if( this.getGracz().getLogin() == null ) System.out.println("brak loginu");
                String log = stat.substring(1);
                if (this.getGracz().getLogin().equals(log)) {
                    rozgrywka.getGracze().add(this.getGracz());
                    this.getGracz().setStanowiskoPrzyStole(this.rozgrywka.getGracze().size() - 1);

                } else {
                    rozgrywka.getGracze().add(new Gracz(log));
                }
                this.rozgrywka.getGracze().elementAt(this.rozgrywka.getGracze().size() - 1).
                        setStanowiskoPrzyStole(this.rozgrywka.getGracze().size() - 1);
                break;
            case 2:
                rozgrywka.budujStol(gracz.getStanowiskoPrzyStole());
                break;
            case 3:
                Integer graczMax = new Integer(stat.charAt(1) - 48);
                Integer poz = (graczMax - gracz.getStanowiskoPrzyStole() +4)%4;
                rozgrywka.getGracze().elementAt(graczMax).setAktualnaStawka(aktualnaMaxStawka);
                widokStol.aktualizujMaxStawke(poz, aktualnaMaxStawka);
                break;
            case 4:
                Integer graczPas = new Integer(stat.charAt(1) - 48);
                Integer poz2 = (graczPas - gracz.getStanowiskoPrzyStole() +4)%4;
                widokStol.spasujMnie(poz2);
                break;
            case 5:
                String kasa = stat.substring(1);
                rozgrywka.setKasaNaStole(Integer.parseInt(kasa));
                widokStol.getJTextField5().setText(kasa);
                break;
            case 6:
                String kartyDoOdkrycia = stat.substring(1);
                int i = 0;
                while( i < kartyDoOdkrycia.length()){
                    ++i; //tu jest kropka
                    Integer gr = kartyDoOdkrycia.charAt(i++) - 48;
                    ++i; //tu tez jest kropka
                    Integer kart = new Integer(-1);
                    for( int j = 0; j < 5; ++j){
                        kart = 10*(kartyDoOdkrycia.charAt(i++)-48);
                        kart += kartyDoOdkrycia.charAt(i++)-48;
                        rozgrywka.getGracze().elementAt(gr).getKarty().elementAt(j).setKtora(kart);
                        rozgrywka.getGracze().elementAt(gr).getKarty().elementAt(j).setOdkryta(true);
                    }

                }
                widokStol.repaint();

                break;
            case 7:
                Integer graczNext = new Integer(stat.charAt(1) - 48);
                String jegoKasa = stat.substring(2);
                widokStol.getTextFieldKasa((graczNext+4 - gracz.getStanowiskoPrzyStole())%4).setText(jegoKasa);
                break;
            case 8:
                widokStol.doNowegoRozdania();
                break;
            default:
                break;

        }
    }

    public Integer wczytajInt(Integer war, Integer min, Integer max, boolean pas) {

        while (true) {
            // w przypadku -1 jest pas
            if (pas == true && war == -1) {
                break;
            }
            if (war >= min && war <= max) {
                break;
            } else {
                System.out.println("Musisz wpisac liczba z przedzialu (" + min + "-" + max + ")\n");
            }
        }
        return war;

    }

    public Integer odbierzInta() throws IOException {
        String odebrane = this.odbierzDane();
        System.out.println("odebrane " + odebrane);
        return new Integer(odebrane);
    }

    public void komunikuj() throws IOException {
        String odebrane;
        Scanner sc = new Scanner(System.in);

        while (true) {
            // odbieramy naglowek
            odebrane = this.odbierzDane();
            //System.out.println(odebrane);

            // serwer pyta ilu nas gra
            if (odebrane.equals("iluGraczy")) {
                widokNowaGra.podajIluGraczy();

            } // pytamy pierwszego gracza jaka jest pula wejsciowa
            else if (odebrane.equals("iloscKasy")) {
                widokNowaGra.podajIleKasy();

            } // pytamy pierwszego gracza jaka jest pula wejsciowa
            else if (odebrane.equals("wczytajKase")) {
                widokNowaGra.wczytajKaseIPokazStol();

            }//odbieramy pewne dane do zapisu o pozostyaluch graczach
            else if (odebrane.equals("staty")) {
                String stat = this.odbierzDane();
                odkodujStaty(stat);

            }// odbieramy wygrana
            else if (odebrane.equals("odbierzWygrana")) {
                Integer kasa = odbierzInta();
                gracz.zwiekszStanKonta(kasa);
                widokStol.getJTextArea1().append("Gratulujemy, wygrales ture i cala forsa ze stolu idzie do Ciebie: " + kasa+"\n");

            } // masz podac teraz stawke na stol
            else if (odebrane.equals("podajStawke")) {
                widokStol.getJTextArea1().append("Podaj stawkę albo spasuj (" + aktualnaMaxStawka + "-" + gracz.getStanKonta() + ") (spasowanie -1)\n");
                widokStol.podajStawke();

            } // dodajesz aktualna stawke
            else if (odebrane.equals("aktualnaStawka")) {
                aktualnaMaxStawka = odbierzInta();
                System.out.println("Aktualna stawka");

            } else if (odebrane.equals("koniecLicytacji")) {
                // tutaj kasujemy wszystkie stawki etc
                widokStol.getJTextArea1().append("Koniec licytacji\n");
                System.out.println("Ilosc pieniedzy: " + this.gracz.getStanKonta());

            } else if (odebrane.equals("nowaTura")) {
                wymieniane = false;
                jeszczeNieZmieniajWidoku = false;
                gracz.nowaTura();
                rozgrywka.nowaTura(gracz.getStanowiskoPrzyStole());
                aktualnaMaxStawka = 0;
                widokStol.repaint();

            //gracz.usunKarty();
            } else if (odebrane.equals("koniecTury")) {
                Integer mojStanKonta = gracz.koniecTury();
                this.out.println(mojStanKonta.toString());

            //gracz.usunKarty();
            } else if (odebrane.equals("podajHierarchie")) {
                this.out.println(gracz.podajHierarchie());

            } // serwer przysyla nam pule wejsciowa
            else if (odebrane.equals("login")) {
                widokNowaGra.podajLogin();

            } // serwer chce powiedziec cos ciekawego wiec warto posluchac
            else if (odebrane.equals("info")) {
                odebrane = this.odbierzDane();
                if (jeszczeNieZmieniajWidoku) {
                    widokNowaGra.getJTextArea1().append(odebrane + "\n");
                } else {
                    widokStol.getJTextArea1().append(odebrane + "\n");
                }

            } // tutaj odbieramy n kart od serwera
            else if (odebrane.equals("wysylanieKart")) {

                // odbieramy n kart
                odebrane = this.odbierzDane();
                Integer ileKart = new Integer(odebrane);
                widokStol.getJTextArea1().append("Otrzymales: " + ileKart + " kart..\n");
                // odbieramy 5 kart
                if (wymieniane) {
                    for (int j = 0; j < 5; ++j) {
                        if (gracz.getKarty().elementAt(j).isDoWymiany()) {
                            odebrane = this.odbierzDane();
                            //System.out.println("odebrana karta: "+odebrane);
                            gracz.dodajKarte(new Integer(odebrane), j);
                            gracz.getKarty().elementAt(j).setDoWymiany(false);
                        }
                    }
                } else {
                    for (int j = 0; j < ileKart; ++j) {
                        odebrane = this.odbierzDane();
                        //System.out.println("odebrana karta: "+odebrane);
                        gracz.dodajKarte(new Integer(odebrane), j);
                    }
                }
                wymieniane = false;
                widokStol.repaint();
                gracz.posortujKarty();
                widokStol.wypiszHierarchie(gracz.wypiszKarty());


            } // wymieniamy karty
            else if (odebrane.equals("ileWymienic")) {
                widokStol.getJTextArea1().append("Ile kart wymienić?\n");
                widokStol.ileKartDoWymiany();
            // odbieramy n kart
            //Integer ileWymienic = sc.nextInt();

            } // koniec gry
            else if( odebrane.equals("chceTwojeKarty")){
                this.out.println(gracz.podajKarty());
            }
            else if (odebrane.equals("bye")) {
                break;
            }


        }
    }
}
